package com.chinatechstar.component.socketio;

import com.chinatechstar.component.commons.utils.Oauth2Utils;
import com.chinatechstar.component.commons.utils.StrUtils;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.annotation.SpringAnnotationScanner;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.provider.OAuth2Authentication;

@Configuration
public class NettySocketConfig {
    @Value("${socketIO.host}")
    private String host;

    @Value("${socketIO.port}")
    private Integer port;

    @Value("${socketIO.maxFramePayloadLength}")
    private int maxFramePayloadLength;

    @Value("${socketIO.maxHttpContentLength}")
    private int maxHttpContentLength;

    @Value("${socketIO.bossCount}")
    private int bossCount;

    @Value("${socketIO.workCount}")
    private int workCount;

    @Value("${socketIO.allowCustomRequests}")
    private boolean allowCustomRequests;

    @Value("${socketIO.upgradeTimeout}")
    private int upgradeTimeout;

    @Value("${socketIO.pingTimeout}")
    private int pingTimeout;

    @Value("${socketIO.pingInterval}")
    private int pingInterval;

    @Bean
    public SocketIOServer socketIOServer() {
        com.corundumstudio.socketio.Configuration config = new com.corundumstudio.socketio.Configuration();

//        config.setHostname(host);
        config.setPort(port);
        config.setMaxFramePayloadLength(maxFramePayloadLength);
        config.setMaxHttpContentLength(maxHttpContentLength);
        config.setBossThreads(bossCount);
        config.setWorkerThreads(workCount);
        config.setAllowCustomRequests(allowCustomRequests);
        config.setUpgradeTimeout(upgradeTimeout);
        config.setPingTimeout(pingTimeout);
        config.setPingInterval(pingInterval);

        // 握手协议参数使用JWT的Token认证方案
        config.setAuthorizationListener(data -> {
            // 可以使用如下代码获取用户密码信息
            String accessToken = data.getSingleUrlParam("token");
            if (StrUtils.isNullOrEmpty(accessToken)) {
                return false;
            }

            OAuth2Authentication authentication = Oauth2Utils.getAuthenticationInOauth2Server(accessToken);
            return authentication != null && authentication.isAuthenticated();
        });

        return new SocketIOServer(config);
    }

    @Bean
    public SpringAnnotationScanner springAnnotationScanner(SocketIOServer socketServer) {
        return new SpringAnnotationScanner(socketServer);
    }
}
